package auth
import (
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"net/http"
	// "strings"
	// "time"
	"github.com/gin-gonic/gin"
	"io"
	"bytes"
)

func AuthWithBodyMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 1. 读取Body内容（注意：读取后需重新填充回RequestBody）
        bodyBytes, err := io.ReadAll(c.Request.Body)
        if err != nil {
            c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Failed to read body"})
            return
        }
        // 关键：将Body重新写回，供后续处理使用
        c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))

        // 2. 计算Body哈希
        bodyHash := sha256.Sum256(bodyBytes)
        encodedBodyHash := base64.StdEncoding.EncodeToString(bodyHash[:])

        // 3. 验证签名（包含bodyHash）
        if !verifySignature(c, encodedBodyHash) {
            c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "Invalid signature"})
            return
        }
        c.Next()
    }
}

func verifySignature(c *gin.Context, body string) bool {
    // 1. 获取必要Header
    ak := c.GetHeader(SIGN_AK_HEADER_NAME)
    timestamp := c.GetHeader(SIGN_TIMESTAMP_HEADER_NAME)
    sign := c.GetHeader(SIGN_SIGN_HEADER_NAME)

    method := c.Request.Method
    url := fmt.Sprintf("%s%s", c.Request.Host, c.Request.RequestURI)
    fmt.Println("url:", url)

    serverSign := GenSignString(ak, timestamp, method, url, body)
    // 6. 比对签名
    // return hmac.Equal([]byte(clientSig), []byte(serverSign))
    return sign == serverSign
}
